package com.wibo.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

import weibo4android.Count;
import weibo4android.Paging;
import weibo4android.Status;
import weibo4android.User;
import weibo4android.Weibo;
import weibo4android.WeiboException;
import weibo4android.org.json.JSONException;

import com.wibo.account.CUserManager;
import com.wibo.account.OAuthConstant;
import com.wibo.account.R;
import com.wibo.account.WiboMainActivity;
import com.wibo.account.WiboMainTabActivity;
import com.wibo.common.FileDbHelper;
import com.wibo.common.NotificationHelper;
import com.wibo.common.Utility;
import com.wibo.service.IWeiboServiceCallback;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

public class WeiboService extends Service {
	
	public static final String TAG = "WeiboService";
	
	private static WeiboService INSTANCE = null;
	
	private static Weibo mWeibo = null;
	private static OAuthConstant mAuthConstant = null;
	protected FileDbHelper mDbHelper = null;
	CUserManager mUserManager = null;
	private NotificationHelper mNotificationHelperComments = null;
	private NotificationHelper mNotificationHelperTransmits = null;
	private NotificationHelper mNotificationHelperFans = null;
	public int mNotificationIdComments = R.string.newComments;
	public int mNotificationIdTransmits = R.string.newTransmits;
	public int mNotificationIdFans = R.string.newFans;
	
	private AlarmManager mAlarmManager;
	private Count mCount = null;
	
	private static final String GET_COUNT_ALARM_ACTION = "com.wibo.getAlarmAction";
	
	public WeiboService() {
		Log.i(TAG, "Construct");
		//super("");
	}
	
	public static WeiboService getServiceInstance(){
		return INSTANCE;
	}

	
	private static final int GET_COUNT_FINISH = 0;
	private static final int GET_COUNT_ERROR = 1;
	
	private static final int GET_HAVE_NEW_WEIBO_FINISH = 2;
	private static final int GET_HAVE_NEW_WEIBO_ERROR = 3;
	private static final int CLEAN_MESSAGE_NEW_WEIBO = 4;
	private static final int CLEAN_COMMENT_NUM = 5;
	private static final int CLEAN_TRANSMIT_NUM = 6;
	private static final int CLEAN_FANS_NUM = 7;
	
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case GET_COUNT_FINISH:
				if (msg.obj != null) {
					Count count = (Count) msg.obj;
					if (count.getComments() > 0){
						if (mNotificationHelperComments == null) {
							mNotificationHelperComments = new NotificationHelper(WeiboService.this, mUserManager.getAccountUser().getName(), 
									mNotificationIdComments, NotificationHelper.NOTIFICATION_COMMENT, 0);
							mNotificationHelperComments.createNotification(count.getComments(), WeiboService.this);
						}else{
							mNotificationHelperComments.updateNotification(count.getComments(), WeiboService.this);
						}
					}
						
					if (count.getMentions() > 0){
						if (mNotificationHelperTransmits == null) {
							mNotificationHelperTransmits = new NotificationHelper(WeiboService.this, mUserManager.getAccountUser().getName(), 
									mNotificationIdTransmits, NotificationHelper.NOTIFICATION_TRANSMIT, 0);
							mNotificationHelperTransmits.createNotification(count.getMentions(), WeiboService.this);
						}else{
							mNotificationHelperTransmits.updateNotification(count.getMentions(), WeiboService.this);
						}
					}
					if (count.getFollowers() > 0){
						if (mNotificationHelperFans == null) {
							mNotificationHelperFans = new NotificationHelper(WeiboService.this, mUserManager.getAccountUser().getName(), 
									mNotificationIdFans, NotificationHelper.NOTIFICATION_FANS, 0);
							mNotificationHelperFans.createNotification(count.getFollowers(), WeiboService.this);
						}else{
							mNotificationHelperFans.updateNotification(count.getFollowers(), WeiboService.this);
						}
					}
					
					synchronized (mCallbacks) {
						final int nCount = mCallbacks.beginBroadcast();
						for(int i = 0; i < nCount; ++i){
							try{
								Log.i(TAG, "getComments" + String.valueOf(count.getComments()));
								Log.i(TAG, "getMentions" + String.valueOf(count.getMentions()));
								Log.i(TAG, "getFollowers" + String.valueOf(count.getFollowers()));
								Log.i(TAG, "getDm" + String.valueOf(count.getDm()));
								Log.i(TAG, "getRt" + String.valueOf(count.getRt()));
								Log.i(TAG, "getId" + String.valueOf(count.getId()));

								mCallbacks.getBroadcastItem(i).unreadComment(count.getComments());
								if (count.getComments() == 0) {
									if (mNotificationHelperComments != null) {
										mNotificationHelperComments.cancelNotification(WeiboService.this);
									}
									Intent intent = new Intent();
									intent.setAction(WiboMainTabActivity.CLEAN_COMMENTS_ACTION);
									sendBroadcast(intent);
								}
								mCallbacks.getBroadcastItem(i).unreadTransmit(count.getMentions());
								if (count.getMentions() == 0) {
									if (mNotificationHelperTransmits != null) {
										mNotificationHelperTransmits.cancelNotification(WeiboService.this);
									}
									Intent intent = new Intent();
									intent.setAction(WiboMainTabActivity.CLEAN_TRANSMITS_ACTION);
									sendBroadcast(intent);
								}
								mCallbacks.getBroadcastItem(i).unreadTotalMessages(count.getComments() + count.getMentions());
								mCallbacks.getBroadcastItem(i).unreadFans(count.getFollowers());
								if (count.getFollowers() == 0) {
									if (mNotificationHelperFans != null) {
										mNotificationHelperFans.cancelNotification(WeiboService.this);
									}
								}
								mCallbacks.getBroadcastItem(i).unreadWeibo(count.getDm());
							}catch(RemoteException e){
								e.printStackTrace();
							}
							
						}
						mCallbacks.finishBroadcast();
					}
				}
				break;
			case GET_COUNT_ERROR:
				break;
			case GET_HAVE_NEW_WEIBO_FINISH:
				synchronized (mCallbacks) {
					final int nCount = mCallbacks.beginBroadcast();
					for(int i = 0; i < nCount; ++i){
						try{
							mCallbacks.getBroadcastItem(i).haveNewWeibo(true);
						}catch(RemoteException e){
							e.printStackTrace();
						}
						
					}
					mCallbacks.finishBroadcast();
				}
				break;
			case GET_HAVE_NEW_WEIBO_ERROR:
				break;
			case CLEAN_MESSAGE_NEW_WEIBO:
				break;
			case CLEAN_COMMENT_NUM:
				if (mNotificationHelperComments != null) {
					mNotificationHelperComments.cancelNotification(WeiboService.this);
				}
				break;
			case CLEAN_TRANSMIT_NUM:
				if (mNotificationHelperTransmits != null) {
					mNotificationHelperTransmits.cancelNotification(WeiboService.this);
				}
				break;
			case CLEAN_FANS_NUM:
				if (mNotificationHelperFans != null) {
					mNotificationHelperFans.cancelNotification(WeiboService.this);
				}
				break;
			}
		}
	};
	
	private void sendMessage(int what, Object obj) {
		Message msg = mHandler.obtainMessage(what, obj);
		mHandler.sendMessage(msg);
	}
	
	private void sendMessage(int what, int arg1, int arg2, Object obj) {
		Message msg = mHandler.obtainMessage(what, arg1, arg2, obj);
		mHandler.sendMessage(msg);
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return mBinder;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		INSTANCE = this;
		
		mUserManager = CUserManager.getInstance(this);
		
		if (mAuthConstant == null)
			mAuthConstant = OAuthConstant.getInstance();

		if (mWeibo == null)
			mWeibo = mAuthConstant.getWeibo();

		if (mDbHelper == null)
			mDbHelper = new FileDbHelper(this);
		
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(GET_COUNT_ALARM_ACTION);
      	registerReceiver(mAlarmBroadcast, intentFilter);
		
		mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
		resetGetCountAlarm(Utility.REFRESH_INTERVAL, Utility.REFRESH_INTERVAL);
		
		intentFilter = new IntentFilter();
		intentFilter.addAction(CLEAN_HOME_ACTION);
		intentFilter.addAction(CLEAN_TRANSMITS_ACTION);
		intentFilter.addAction(CLEAN_COMMENTS_ACTION);
		intentFilter.addAction(CLEAN_FANS_ACTION);
		registerReceiver(mSetBarBroadcast, intentFilter);
	}
	

	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
		
		if (Utility.isNetworkAvailable(WeiboService.this)) {
			Log.e("start", "server onstart");
			SharedPreferences settings = getSharedPreferences(WiboMainActivity.ID_PAIR, 0);
			long newestId = settings.getLong(WiboMainActivity.NEWEST_ID, -1);
			getUnread(newestId);
		}
	}
	
	public static final String CLEAN_HOME_ACTION = "com.wibo.account.cleanHome";
	public static final String CLEAN_COMMENTS_ACTION = "com.wibo.account.cleanComments";
	public static final String CLEAN_TRANSMITS_ACTION = "com.wibo.account.cleanTransmits";
	public static final String CLEAN_FANS_ACTION = "com.wibo.account.cleanFans";
	
	
	BroadcastReceiver mSetBarBroadcast = new BroadcastReceiver() {
		
		public void onReceive(Context context, Intent intent) {
			if(intent.getAction().equals(CLEAN_HOME_ACTION)) {
				sendMessage(CLEAN_MESSAGE_NEW_WEIBO, null);
			} else if(intent.getAction().equals(CLEAN_COMMENTS_ACTION)) {
				sendMessage(CLEAN_COMMENT_NUM, null);
			} else if(intent.getAction().equals(CLEAN_TRANSMITS_ACTION)) {
				sendMessage(CLEAN_TRANSMIT_NUM, null);
			} else if(intent.getAction().equals(CLEAN_FANS_ACTION)) {
				sendMessage(CLEAN_FANS_NUM, null);
			}
		}
	};


	private final IWeiboService.Stub mBinder = new IWeiboService.Stub() {
		public void unregisterCallback(IWeiboServiceCallback cb)
				throws RemoteException {
			if (cb != null) {
				mCallbacks.unregister(cb);
			}

		}

		public void registerCallback(IWeiboServiceCallback cb)
				throws RemoteException {
			if (cb != null) {
				mCallbacks.register(cb);
			}
	
		}

		@Override
		public void getUnreadCount(long weiboId) throws RemoteException {
			getUnread(weiboId);			
		}

		@Override
		public void resetCount(int type) throws RemoteException {
			setUnread(type);
		}
	};
	
	private final RemoteCallbackList<IWeiboServiceCallback> mCallbacks = new RemoteCallbackList<IWeiboServiceCallback>();

	private Thread mGetUnreadThread = null;
	
	private void getUnread(final long weiboId) {
		if (mGetUnreadThread != null) {
			if (mGetUnreadThread.isAlive()) {
				mGetUnreadThread.interrupt();
			}
			mGetUnreadThread = null;
		}
		
		mGetUnreadThread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					if (Utility.isNetworkAvailable(WeiboService.this)) {
						if (mUserManager.getAccountUser() != null) {
							mCount = mWeibo.getUnread(1, weiboId);
							
							if (mCount != null) {
								sendMessage(GET_COUNT_FINISH, mCount);
								
								if (weiboId > 0) {
									Paging paging = new Paging(1, 1);
									paging.setSinceId(weiboId + 1);
									List<Status> statuses = null;
									statuses = mWeibo.getFriendsTimeline(paging);
									
									if (statuses.size() >= 1) {
										sendMessage(GET_HAVE_NEW_WEIBO_FINISH, null);
									}
								}
								mUserManager.setLastGetUnread(System.currentTimeMillis());
								
//								boolean cleanSuc = mWeibo.resetCount(1);
//								cleanSuc = mWeibo.resetCount(2);
//								cleanSuc = mWeibo.resetCount(4);
								
							}else{
								sendMessage(GET_COUNT_ERROR, null);
							}
						}else{
							User user = mWeibo.verifyCredentials();
							
							if (user != null) {
								mUserManager.setAccountUser(user);
								mUserManager.insertUserToDB(mDbHelper, user, Utility.USER_MYSELF);
								mUserManager.setUserId(user.getId());
							}else{
								user = mWeibo.verifyCredentials();
								
								if (user != null) {
									mUserManager.setAccountUser(user);
								}
							}
						}
					}
				} catch (WeiboException e) {
					e.printStackTrace();
					sendMessage(GET_COUNT_ERROR, null);
				} catch (JSONException e) {
					sendMessage(GET_COUNT_ERROR, null);
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
				
				Log.i(TAG, "--------------reset getCount Alarm--------------");
				resetGetCountAlarm(Utility.REFRESH_INTERVAL, Utility.REFRESH_INTERVAL);
			}
		});
		mGetUnreadThread.start();
	}
	
	private void setUnread(final int type) {
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					boolean cleanSuc = mWeibo.resetCount(type);
					
					if (cleanSuc) {
						switch (type) {
						case 0:
							break;
						case 1:
							if (mNotificationHelperComments != null){
								mNotificationHelperComments.cancelNotification(WeiboService.this);
							}
								
							break;
						case 2:
							if (mNotificationHelperTransmits != null){
								mNotificationHelperTransmits.cancelNotification(WeiboService.this);
							}
							
							break;
						case 3:
							break;
						case 4:
							if (mNotificationHelperFans != null){
								mNotificationHelperFans.cancelNotification(WeiboService.this);
							}
							Intent intent = new Intent();
							intent.setAction(WiboMainTabActivity.CLEAN_FANS_ACTION);
							sendBroadcast(intent);	
							break;
						}
					}
				} catch (WeiboException e) {
					e.printStackTrace();
					//sendMessage(GET_COUNT_ERROR, null);
				}
			}
		}).start();
	}
	
	@Override
	public void onDestroy() {
		Log.i(TAG, "Service Destroy!");		
		if (mGetUnreadThread != null) {
			if (mGetUnreadThread.isAlive()) {
				mGetUnreadThread.interrupt();
			}
			mGetUnreadThread = null;
		}
		
		mAlarmManager.cancel(getCountCheckAlarmIntent());
		
		try{
			unregisterReceiver(mAlarmBroadcast);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		try{
			unregisterReceiver(mSetBarBroadcast);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		super.onDestroy();
	}

	
	// 设置闹钟
	private void resetGetCountAlarm(long timeStart, long timeRepeat){
		
		PendingIntent pendingIntent = getCountCheckAlarmIntent();
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(System.currentTimeMillis());
		
		cal.add(Calendar.SECOND, (int)timeStart);
		mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), timeRepeat * 1000, pendingIntent);
	}
	
	private PendingIntent getCountCheckAlarmIntent(){
		Intent intent = new Intent();
		intent.setAction(GET_COUNT_ALARM_ACTION);
		return PendingIntent.getBroadcast(this, 0, intent, 0); 
	}
	
	BroadcastReceiver mAlarmBroadcast = new BroadcastReceiver() {
		
		public void onReceive(Context context, Intent intent) {
			if(intent.getAction().equals(GET_COUNT_ALARM_ACTION)){
				SharedPreferences settings = getSharedPreferences(WiboMainActivity.ID_PAIR, 0);
				long newestId = settings.getLong(WiboMainActivity.NEWEST_ID, -1);
				getUnread(newestId);
			}
		}
	};
}
